<?php

namespace app\components;

// use phpDocumentor\Reflection\DocBlock\Tags\Var_;

use yii;
use yii\base\ErrorException;
use app\components\Api;
use app\components\Log;
use app\components\Loyalty;
use yii\web\ServerErrorHttpException;

/**
 * all loyalty api config and functions
 */
class JselectLoyaltyUAT extends Loyalty
{
    /**
     * return the loyalty api basic config parameters
     * @return array or string
     */
    public static function config($config = null)
    {         
        $configs = [
            'loyalty_url' => 'http://loyalty-uat.xgate.com:8080/index.php/',
            'authentication' => [
                'account_id' => 'demo',
                'username' => 'admin@chn.jselect.com',
                'password' => 'xg1234',
            ],
            'tenant_id' => 287,
        ];

        return is_null($config) ? $configs : $configs[$config];
    }

    /**
     * magic static call loyalty api
     */
    public static function __callStatic($name, $arguments)
    {
        // 检查Call的方法是否在API Maps
        $apiMap = static::apiMap();
        if (!array_key_exists($name, $apiMap)) {
            throw new ServerErrorHttpException('Error: the static method [ Loyalty::' . $name . '() ] don`t exists.');
        } else {
            $api = $apiMap[$name];
        }

        // 如果不需要传post字段，则allowEmpty为true
        if (isset($api['allowEmpty']) && $api['allowEmpty'] == true) {
            $validate_result = true;
            if (empty($arguments[0])) {
                $data = [];
            } else {
                $data = $arguments[0];
            }
        } else {
            // 如果是post请求，需要验证post字段是否正确
            if ($api['method'] == 'post') {
                $validate_result = static::validate($api, $arguments);
                $data = $arguments[0];
            } else {
                // get请求
                $validate_result = true;
                $data = [];
            }
        }

        // 执行API Call
        if ($validate_result === true) {
            return static::call($api, $data);
        }
    }

    /**
     * validate the params
     * @param string $api
     * @param array $data
     * @return string $param or boolean true
     */
    public static function validate($api, $arguments)
    {
        if (empty($arguments[0])) {
            throw new ServerErrorHttpException('Error: post data is **empty** when call [ Loyalty::' . $api['controller'] . '_' . $api['action'] . '() ].');
        }
        $data = $arguments[0];

        $params = $api['params'];

        // build a new array without "*"
        $match = [];
        foreach ($params as $param) {
            $default_param = strstr($param, '*', true);
            if ($default_param !== false) {
                $match[] = $default_param;
            } else {
                $match[] = $param;
            }
        }

        // validate the data unavailable parameter and null parameter
        foreach ($data as $key => $value) {
            if (!in_array($key, $match)) {
                throw new ServerErrorHttpException('Error: the param: [' . $key . '] is **unavailable** when call [ Loyalty::' . $api['controller'] . '_' . $api['action'] . '() ].');
            }
            if ($value === null || $value === false) {
                throw new ServerErrorHttpException('Error: the param: [' . $key . '] is **null** when call [ Loyalty::' . $api['controller'] . '_' . $api['action'] . '() ].');
            }
        }

        // validate the reuired parameter
        foreach ($params as $param) {
            $param = strstr($param, '*', true);
            if ($param !== false) {
                if (empty($data[$param])) {
                    throw new ServerErrorHttpException('Error: the param: [' . $param . '] is **required** when call [ Loyalty::' . $api['controller'] . '_' . $api['action'] . '() ].');
                }
            }
        }

        return true;
    }

    /**
     * use Api component call loyalty api
     * @param array $api
     * @param array | null $data
     */
    public static function call($api, $data)
    {
        $configs = static::config();
        
        $data = array_merge($data, $configs['authentication']);
        // 判断连接的最后是否带 "/"
        if (substr($configs['loyalty_url'], -1) == '/') {
            $url = $configs['loyalty_url'] . $api['controller'] . '/' . $api['action'];
        } else {
            $url = $configs['loyalty_url'] . '/' . $api['controller'] . '/' . $api['action'];
        }       
        if ($api['method'] == 'post') {
            $re = Api::post($url, $data);
        } else {
            $re = Api::get($url);
        }
        if ($re) {
            $re = Api::parseJSON($re);
        } else {
            $re = false;
        }
        return $re;        
        // 自行在业务流程中判断Api的返回结果
        // 不抛出错误，因为业务流程中我们需要在报错信息
        // if (isset($re['status']) && $re['status'] == 'error') {
            // throw new ServerErrorHttpException('Loyalty API Error, Error msg: [' . $re['message'] . '], When call [' . $url . ']');
        // } else {
            // return $re;
        // }
    }

}